package com.skrabacz.kinetic.buisness.logic;

import javax.management.InvalidAttributeValueException;

public class SimpleBall implements Ball {

	private double speed;
	private Direction direction;
	private Board board;
	private Point currentPosition;
	private int verticalShift;
	private int horizontalShift;

	public SimpleBall() {
		this(0d);
	}

	public SimpleBall(double speed) {
		this(0d, Direction.North);
	}

	public SimpleBall(double speed, Direction direction) {
		this(speed, direction, new Node(), new Matrix());
	}

	public SimpleBall(double speed, Direction direction, Point startedPoint, Board board) {
		this.speed = speed;
		this.direction = direction;
		currentPosition = startedPoint;
		this.board = board;
	}

	@Override
	public boolean moveToDirection(Direction direction) throws InvalidAttributeValueException {
		if (isReachable(currentPosition, direction)) {
			currentPosition = board.getPoint(currentPosition.getCoordinateX() + verticalShift,
					currentPosition.getCoordinateY() + horizontalShift);
			return true;
		}
		return false;
	}

	@Override
	public boolean isReachable(Point node, Direction direction) {
		switch (direction) {
		case North:
			setUpShifts(-1, 0);
			return ((node.getCoordinateX() - 1) >= 0 ? true : false);
		case East:
			setUpShifts(0, 1);
			return ((node.getCoordinateY() + 1) <= board.getWidth() ? true : false);
		case South:
			setUpShifts(1, 0);
			return ((node.getCoordinateX() + 1) <= board.getHeight() ? true : false);
		case West:
			setUpShifts(0, -1);
			return ((node.getCoordinateY() - 1) >= 0 ? true : false);
		default:
			return false;
		}
	}

	private void setUpShifts(int vertical, int horizontal) {
		verticalShift = vertical;
		horizontalShift = horizontal;
	}

	@Override
	public double getSpeed() {
		return speed;
	}

	@Override
	public Direction getDirection() {
		return direction;
	}

	protected void setSpeed(double speed) {
		this.speed = speed;
	}

	protected void setDirection(Direction direction) {
		this.direction = direction;
	}

	protected void setBoard(Board board) {
		this.board = board;
	}

	protected void setCurrentPosition(Point currentPosition) {
		this.currentPosition = currentPosition;
	}

	@Override
	public Point getCurrentPosition() {
		return currentPosition;
	}

	@Override
	public Board getBoard() {
		return board;
	}
}
